<!--
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
-->

<template>
  <div class="data-list-tree">
    <div class="data-list-top">
      <span>{{ $t('rootPage.dataList') }}</span>
    </div>
    <div class="data-list-btn">
      <el-button @click="newSource">
        <svg class="icon" aria-hidden="true">
          <use xlink:href="#icon-add"></use>
        </svg>
        {{ $t('rootPage.newdatasource') }}
      </el-button>
      <el-button @click="sqlClick">
        <svg class="icon" aria-hidden="true">
          <use xlink:href="#icon-add"></use>
        </svg>
        {{ $t('rootPage.newQueryWindow') }}
      </el-button>
    </div>
    <!-- <div class="data-list-input">
      <el-input size="small" placeholder="" v-model="searchVal">
        <template #suffix>
          <i @click="searchClick" class="el-icon-search"></i>
        </template>
      </el-input>
    </div> -->
    <el-tree
      :expand-on-click-node="true"
      :default-expanded-keys="treeExpandKey"
      v-if="store.state?.userInfo?.userId !== undefined"
      ref="treeRef"
      highlight-current
      node-key="id"
      :indent="20"
      :props="treeProps"
      @node-click="nodeClick"
      :load="loadNode"
      lazy
      :current-node-key="nodekey"
      :key="treeKey"
      @node-expand="expandNode"
      @node-collapse="collapseNode"
    >
      <template #default="{ node, data }">
        <span class="custom-tree-node">
          <icon-types :data="data" :nodekey="nodekey" />
          <span>{{ node.label }}</span>
        </span>
      </template>
    </el-tree>
    <NewSource v-if="showDialog" :func="func" :serverId="null" :showDialog="showDialog" :types="types" @close="close()" @successFunc="successFunc(data)" />
    <SqlDrawer v-if="showDrawer" :func="funcdata" @coloseDrawer="coloseDrawer"></SqlDrawer>
  </div>
</template>

<script>
import { ElTree, ElButton } from 'element-plus';
import { reactive, ref, computed } from 'vue';
import { useStore } from 'vuex';
import IconTypes from './iconTypes.vue';
import axios from '@/util/axios.js';
import { useRouter } from 'vue-router';
import { useI18n } from 'vue-i18n';
import NewSource from '../../Source/components/newSource';
import SqlDrawer from '../../SqlSerch/components/sqlDrawer';

export default {
  name: 'DataListTree',
  props: ['handleNodeClick', 'nodekey', 'func'],
  setup(props) {
    const treeProps = reactive({
      label: 'name',
      children: 'zones',
      isLeaf: 'leaf',
      disabled: 'disabled',
    });
    const searchVal = ref('');
    const treeRef = ref(null);
    const treeExpandKey = ref([]);
    const store = useStore();
    const showDialog = ref(false);
    const showDrawer = ref(false);
    const types = ref(null);
    const treeKey = ref(1);
    const funcdata = reactive(props.func);
    const router = useRouter();
    const { t } = useI18n();

    const searchClick = () => {
      console.log('jj');
    };

    const nodeClick = (data, node) => {
      props.handleNodeClick(data, node);
    };

    /**
     * 新建数据连接
     */
    const newSource = () => {
      showDialog.value = true;
      types.value = 0;
    };
    /**
     * 关闭或者取消新增/编辑数据连接操作
     */
    const close = () => {
      showDialog.value = false;
      types.value = 0;
    };
    /**
     * 新增或编辑数据源成功回调
     */
    const successFunc = () => {
      showDialog.value = false;
      types.value = 0;
    };

    const sqlClick = () => {
      showDrawer.value = true;
    };

    const updateTree = (params, clear) => {
      if (params) {
        let arr = treeExpandKey.value;
        if (clear) {
          arr = [];
        }
        arr = arr.concat(params);
        treeExpandKey.value = arr;
      }
      treeKey.value += 1;
    };

    const coloseDrawer = () => {
      showDrawer.value = false;
    };

    const expandNode = (data) => {
      let arr = treeExpandKey.value;
      arr.push(data.id);
      treeExpandKey.value = arr;
    };

    const collapseNode = (data) => {
      let arr = treeExpandKey.value;
      let index = arr.indexOf(data.id);
      if (index !== -1) {
        arr.splice(index, 1);
      }
      treeExpandKey.value = arr;
    };

    const recurseDeviceTree = (data, node) => {
      let newDevice = {
        id: node.data.id + ':newdevice',
        name: computed(() => t(`databasem.newDevice`)),
        type: 'newdevice',
        leaf: true,
        parent: node.data,
        connectionid: node.data.connectionid,
        storagegroupid: node.data.storagegroupid,
      };
      let childs = data.map((e) => {
        let child = {
          parent: node.data,
          name: e.name,
          id: node.data.id + e.name + 'device',
          type: 'device',
          // leaf: e.children === null ? true : false,
          leaf: false,
          rawid: e.name,
          storagegroupid: node.data.storagegroupid,
          connectionid: node.data.connectionid,
          deviceid: e.name,
        };
        // if (e.children) {
        let innerChilds = recurseDeviceTree(e.children || [], { data: child });
        child.zones = innerChilds;
        // }
        return child;
      });
      childs.unshift(newDevice);
      return childs;
    };

    const loadNode = (node, resolve) => {
      if (node?.data?.zones) {
        resolve(node.data.zones);
        return;
      }
      if (node.level === 0) {
        axios
          .get('/servers', { params: { userId: store.state?.userInfo?.userId } })
          .then((res) => {
            if (res?.code === '0') {
              let data = (res.data.aliasList || []).map((e) => {
                return {
                  name: e.alias,
                  id: e.id + 'connection',
                  type: 'connection',
                  rawid: e.id,
                  connectionid: e.id,
                };
              });
              if (data.length === 0) {
                router.push({ name: 'Empty' });
              }
              if (data.length > 0 && store.state.firstPageLoad) {
                // router.push({ name: 'Root' });
                props.func.addTab(data[0].id, {}, true);
              }
              store.commit('setFirstPageLoad', false);
              return resolve(data);
            } else {
              resolve([]);
            }
          })
          .catch(() => {
            resolve([]);
          });
      }
      if (node.level === 1) {
        axios
          .get(`/servers/${node.data.rawid}/storageGroups`, {})
          .then((res) => {
            let newStorageGroup = {
              id: node.data.id + ':newstoragegroup',
              name: computed(() => t(`databasem.newStoreGroup`)),
              parent: node.data,
              type: 'newstorageGroup',
              leaf: true,
              connectionid: node.data.connectionid,
            };
            let queryList = {
              id: node.data.id + ':querylist',
              name: computed(() => t(`databasem.query`)),
              parent: node.data,
              type: 'querylist',
              connectionid: node.data.connectionid,
            };
            if (res?.code === '0') {
              let data = (res.data || []).map((e) => {
                return {
                  parent: node.data,
                  name: e.groupName,
                  id: node.data.id + e.groupName + 'storageGroup',
                  type: 'storageGroup',
                  rawid: e.groupName,
                  storagegroupid: e.groupName,
                  connectionid: node.data.connectionid,
                };
              });
              data.unshift(queryList);
              data.unshift(newStorageGroup);
              return resolve(data);
            } else {
              resolve([]);
            }
          })
          .catch(() => {
            resolve([]);
          });
      }
      if (node.level === 2 && node.data.type === 'storageGroup') {
        let groupName = node.data.rawid;
        let serverId = node.data.parent.rawid;
        axios
          .get(`/servers/${serverId}/storageGroups/${groupName}/devices/tree`, {})
          .then((res) => {
            if (res?.code === '0') {
              if (!res.data) {
                let newDevice = {
                  id: node.data.id + ':newdevice',
                  name: computed(() => t(`databasem.newDevice`)),
                  type: 'newdevice',
                  leaf: true,
                  parent: node.data,
                  connectionid: node.data.connectionid,
                  storagegroupid: node.data.storagegroupid,
                };
                resolve([newDevice]);
                return;
              }
              if (res.data.name === null) {
                let childs = recurseDeviceTree(res.data.children || [], node);
                resolve(childs);
              } else {
                let rootDevice = {
                  // parent: node.data,
                  name: res.data.name,
                  // id: node.data.id + res.data.name + 'device',
                  // type: 'device',
                  // leaf: false,
                  // rawid: res.data.name,
                  // storagegroupid: node.data.storagegroupid,
                  // connectionid: node.data.connectionid,
                  // deviceid: res.data.name,
                  children: res.data.children,
                };
                let childs = recurseDeviceTree([rootDevice] || [], node);
                node.zones = childs;
                resolve(childs);
              }
            } else {
              resolve([]);
            }
          })
          .catch(() => {
            resolve([]);
          });
      }
      if (node.level === 2 && node.data.type === 'querylist') {
        let serverId = node.data.parent.rawid;
        axios
          .get(`/servers/${serverId}/query`, {})
          .then((res) => {
            let newQuery = {
              id: node.data.id + ':newquery',
              name: computed(() => t(`databasem.newQuery`)),
              type: 'newquery',
              leaf: true,
              parent: node.data,
              storagegroupid: node.data.storagegroupid,
              connectionid: node.data.connectionid,
            };
            if (res?.code === '0') {
              let data = (res.data || []).map((e) => {
                return {
                  parent: node.data,
                  name: e.queryName,
                  id: node.data.id + e.id + 'query',
                  type: 'query',
                  leaf: true,
                  rawid: e.id,
                  storagegroupid: node.data.storagegroupid,
                  connectionid: node.data.connectionid,
                  queryid: e.id,
                };
              });
              data.unshift(newQuery);
              return resolve(data);
            } else {
              resolve([]);
            }
          })
          .catch(() => {
            resolve([]);
          });
      }
    };

    return {
      collapseNode,
      expandNode,
      treeExpandKey,
      treeKey,
      store,
      loadNode,
      searchClick,
      nodeClick,
      newSource,
      treeProps,
      searchVal,
      treeRef,
      close,
      successFunc,
      showDialog,
      types,
      showDrawer,
      updateTree,
      sqlClick,
      coloseDrawer,
      funcdata,
    };
  },
  components: {
    ElTree,
    IconTypes,
    ElButton,
    // ElInput,
    NewSource,
    SqlDrawer,
  },
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
.data-list-tree {
  height: 100%;
  overflow: auto;
  .data-list-top {
    color: #333;
    font-size: 12px;
    line-height: 20px;
    text-align: left;
    margin: 14px 20px;
    font-weight: 600;
  }
  .data-list-btn {
    text-align: left;
    padding: 0 0 14px;
    border-width: 0;
    border-bottom-width: 1px;
    border-style: solid;
    border-color: #f5f5f7;
    margin: 0 14px 14px;
    &::v-deep {
      .el-button {
        border-width: 0;
        background-color: #f9fbfc;
        color: #333;
        font-size: 12px;
        &:hover {
          background-color: #edf8f5;
          color: #16c493;
        }
        .icon {
          font-size: 14px;
          margin-right: 8px;
        }
      }
    }
  }
  .data-list-input {
    margin: 0 20px 15px;
  }
  .custom-tree-node {
    font-size: 12px;
    color: #333;
  }
  ::v-deep(.el-tree) {
    height: calc(100% - 105px);
    width: 100%;
    overflow: auto;
    .el-tree-node {
      min-width: fit-content;
      &.is-current > .el-tree-node__content > .custom-tree-node {
        & > span {
          color: $theme-color;
        }
      }
    }
    .el-tree-node__content {
      min-width: fit-content;
    }
  }
}
</style>
